﻿\subsection{栈内存管理}

与堆类似，栈是一种程序运行时动态分配的内存空间。
栈相较于堆的不同在于，栈的大小在创建时是确定的，且其容量远小于堆的容量。
栈空间的使用和分配相较于堆效率更高，在栈中创建高级语言的变量（不初始化）只需要对 \lstinline{ESP} 寄存器进行操作，而堆则需要遍历堆描述符，寻找可用空间。

\subsubsection{栈空间分配与回收}

栈与堆一样，可以位于用户空间，也可以处于内核空间。
位于内核空间的栈大小都是固定的，本设计中内核空间的栈按照两个页面的大小（\Bytes{8192}）边界对齐，并且不能出现缺页（即不采用预分配策略），其原因在实现进程和线程时将予以解释。
位于用户空间的栈大小可根据线程的需要确定，按照一个页面的大小边界对齐，采用预分配策略创建。
栈空间的分配与回收与虚拟页面分配和回收类似，区别在于栈空间分配是从高地址向低地址检索，此处不再赘述。

\subsubsection{栈空间保护}

使用栈时有可能发生溢出的情况。
对可在页表中保留一条页表项，该页表项引用一个缺失的的虚拟页面——保护页（Guard Page），如图 \ref{STACK_PROTECTION}，当发生栈溢出时，将访问到该保留页表项对应的虚拟页面触发缺页故障，进而使操作系统获知发生了栈溢出。

\begin{figure}[h!]
    \Centering
    \caption{栈溢出检测——保护页}
    \label{STACK_PROTECTION}
    \includegraphics[scale=0.75]{build/Paper/Assets/StackProtection.pdf}
\end{figure}
